﻿/*********************************************************
 * 开发人员：小兵
 * 创建时间：2012-10-22 13:56:47
 * 描述说明：
 * 
 * 更改历史：
 * 
 * *******************************************************/
namespace Mozlite.Components
{
    using System;
    using System.Web;
    using System.Data;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web.Routing;

    /// <summary>
    /// 分类基类。
    /// </summary>
    /// <typeparam name="T">分类类型。</typeparam>
    public abstract class BaseCategory<T> : IRecursion<T> where T : BaseCategory<T>, new()
    {
        /// <summary>
        /// 初始化类<see cref="BaseCategory&lt;T&gt;"/>。
        /// </summary>
        protected BaseCategory() {
            CultureName = AppContext.Current.CultureName;
        }

        #region properties
        /// <summary>
        /// 分类ID。
        /// </summary>
        public int CategoryID { get; set; }
        /// <summary>
        /// 唯一ID。
        /// </summary>
        public string CategoryKey { get; set; }
        /// <summary>
        /// 分类名称。
        /// </summary>
        public string CategoryName { get; set; }
        /// <summary>
        /// 父分类。
        /// </summary>
        public int ParentID { get; set; }
        /// <summary>
        /// 区域语言。
        /// </summary>
        public string CultureName { get; set; }
        /// <summary>
        /// Logo地址。
        /// </summary>
        public string LogoUrl { get; set; }
        /// <summary>
        /// 排序。
        /// </summary>
        public int SortOrder { get; set; }
        /// <summary>
        /// 创建日期。
        /// </summary>
        public DateTime CreateDate { get; set; }
        /// <summary>
        /// 最后更新时间。
        /// </summary>
        public DateTime LastUpdateDate { get; set; }
        /// <summary>
        /// 描述。
        /// </summary>
        public string Description { get; set; }
        /// <summary>
        /// 默认前台访问地址。
        /// </summary>
        public string DefaultUrlFormat { get; set; }
        /// <summary>
        /// 前台访问分页地址。
        /// </summary>
        public string PagerUrlFormat { get; set; }
        /// <summary>
        /// 产品实例详细信息页面地址格式。
        /// </summary>
        public string DetailUrlFormat { get; set; }
        /// <summary>
        /// 用户组。
        /// </summary>
        public RoleLevel RoleLevel { get; set; }
        #endregion

        #region IRecursion
        private T parent;
        /// <summary>
        /// 父导航。
        /// </summary>
        public T Parent
        {
            get
            {
                if (parent == null)
                    parent = Categories<T>.GetCategory(ParentID, this.CultureName);
                return parent;
            }
        }
        private List<T> children;
        /// <summary>
        /// 子导航。
        /// </summary>
        public List<T> Children
        {
            get
            {
                if (children == null)
                    Categories<T>.GetCategoriesByParentID(this.CultureName).TryGetValue(this.CategoryID, out children);
                return children;
            }
        }
        /// <summary>
        /// 是否含有子导航。
        /// </summary>
        public bool HasChildren
        {
            get { return Children != null && Children.Count > 0; }
        }
        /// <summary>
        /// 是否最高级。
        /// </summary>
        public bool IsToppest
        {
            get
            {
                return this.CategoryID == 0;
            }
        }

        private string childrenIDs;
        /// <summary>
        /// 获取子分类ID。
        /// </summary>
        public string ChildrenIDs
        {
            get
            {
                if (IsToppest)
                    return null;
                if (childrenIDs == null)
                {
                    ((T)this).Recurse<T>(cat =>
                    {
                        if (childrenIDs != null)
                            childrenIDs += ",";
                        childrenIDs += cat.CategoryID;
                    });
                }
                return childrenIDs;
            }
        }
        #endregion

        #region modules
        /// <summary>
        /// 获取{ckey}和{cid}路由对象实例。
        /// </summary>
        /// <param name="keys">路由集合对象。</param>
        /// <returns>返回{ckey}和{cid}路由对象实例。</returns>
        protected IDictionary<string, object> GetRouteObject(IDictionary<string, object> keys = null)
        {
            if(keys == null)
                keys = new RouteValueDictionary();
            if(CategoryKey.HasValue())
                keys.Add("ckey", CategoryKey);
            else
                keys.Add("cid", CategoryID);
            return keys;
        }

        /// <summary>
        /// 获取模型URL地址。
        /// </summary>
        /// <param name="func">返回模型格式地址。</param>
        /// <param name="urlFormat">当前类替换地址。</param>
        /// <param name="routes">路由实例。</param>
        /// <param name="areaName">区域名称。</param>
        /// <returns>返回模型URL地址。</returns>
        protected string GetModuleUrl(Func<ContentModule, string> func, string urlFormat = null, IDictionary<string, object> routes = null, string areaName = null)
        {
            var url = urlFormat;
            if(string.IsNullOrEmpty(url) && Module != null)
                url = func(Module);
            routes = GetRouteObject(routes);
            return Routes.GetFormattedUrl(url, routes, areaName);
        }

        /// <summary>
        /// 获取模型URL地址。
        /// </summary>
        /// <param name="func">返回模型格式地址。</param>
        /// <returns>返回模型URL地址。</returns>
        protected string GetBackendModuleUrl(Func<ContentModule, string> func)
        {
            if(Module != null)
            {
                var url = func(Module);
                var routes = GetRouteObject();
                return Routes.GetFormattedUrl(url, routes, Consts.Backend);
            }
            return null;
        }
        
        /// <summary>
        /// 模型ID。
        /// </summary>
        public virtual Guid ModuleID { get; set; }

        private ContentModule module;
        /// <summary>
        /// 当前模型。
        /// </summary>
        protected ContentModule Module
        {
            get
            {
                if (module == null)
                    module = ContentModules.Get(ModuleID);
                return module;
            }
        }

        /*
         ~/abc/default
         {key}
         http://
         */
        private string defaultUrl;
        /// <summary>
        /// 前台显示默认地址。
        /// </summary>
        public string DefaultUrl
        {
            get
            {
                if(defaultUrl == null)
                {
                    defaultUrl = GetModuleUrl(m => m.DefaultUrl, DefaultUrlFormat);
                }
                return defaultUrl;
            }
        }

        /// <summary>
        /// 模型名称。
        /// </summary>
        public string ModuleName
        {
            get
            {
                if(Module != null)
                    return Module.ModuleName;
                return null;
            }
        }

        private string pagerUrl;
        /// <summary>
        /// 前台默认分类分页页面地址。
        /// </summary>
        public string PagerUrl
        {
            get
            {
                if (pagerUrl == null)
                {
                    pagerUrl = GetModuleUrl(m => m.PagerUrl, PagerUrlFormat);
                }
                return pagerUrl;
            }
        }

        /// <summary>
        /// 前台子项详细信息URL地址。
        /// </summary>
        /// <param name="urlFormat">子项前台访问地址。</param>
        /// <param name="keys">路由匿名对象。</param>
        /// <returns>返回子项详细信息URL地址。</returns>
        public string GetDetailUrl(string urlFormat, object keys)
        {
            if(string.IsNullOrEmpty(urlFormat))
                urlFormat = DetailUrlFormat;
            IDictionary<string, object> routes = new RouteValueDictionary(keys);
            return GetModuleUrl(m => m.DetailUrl, urlFormat, routes);
        }

        private string backendUrl;
        /// <summary>
        /// 后台分类默认列表。
        /// </summary>
        public string BackendUrl
        {
            get
            {
                if (backendUrl == null)
                    backendUrl = GetBackendModuleUrl(m => m.BackendUrl);
                return backendUrl;
            }
        }
        private string backendEditUrl;
        /// <summary>
        /// 后台分类分页列表。
        /// </summary>
        public string BackendEditUrl
        {
            get
            {
                if (backendEditUrl == null)
                    backendEditUrl = GetBackendModuleUrl(m => m.BackendEditUrl);
                return backendEditUrl;
            }
        }
        private string backendPagerUrl;
        /// <summary>
        /// 后台分类分页页面地址。
        /// </summary>
        public string BackendPagerUrl
        {
            get
            {
                if (backendPagerUrl == null)
                    backendPagerUrl = GetBackendModuleUrl(m => m.BackendPagerUrl);
                return backendPagerUrl;
            }
        }
        private string backendPublicUrl;
        /// <summary>
        /// 发布产品地址。
        /// </summary>
        public string BackendPublicUrl
        {
            get
            {
                if (backendPublicUrl == null)
                    backendPublicUrl = GetBackendModuleUrl(m => m.BackendPublicUrl);
                return backendPublicUrl;
            }
        }
        private string tableName;
        /// <summary>
        /// 获取表格名称。
        /// </summary>
        protected internal string TableName
        {
            get
            {
                if(Module != null)
                    tableName = Module.CategoryTableName;
                return tableName;
            }
        }
        private string itemTableName;
        /// <summary>
        /// 获取表格名称。
        /// </summary>
        protected internal string ItemTableName
        {
            get
            {
                if(Module != null)
                    itemTableName = Module.ItemTableName;
                return itemTableName;
            }
        }
        #endregion

        #region helpers
        /// <summary>
        /// 保存分类。
        /// </summary>
        /// <returns>返回保存结果。</returns>
        public bool Save()
        {
            return Categories<T>.Save(this as T);
        }

        /// <summary>
        /// 判断键是否存在。
        /// </summary>
        /// <returns>返回键是否存在。</returns>
        public bool IsKeyExisted()
        {
            return Categories<T>.IsKeyExisted((T)this);
        }

        /// <summary>
        /// 判断名称是否存在。
        /// </summary>
        /// <returns>返回键是否存在。</returns>
        public bool IsNameExisted()
        {
            return Categories<T>.IsNameExisted((T)this);
        }
        #endregion
    }
}
